﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Printing;
using System.Linq;
using System.Text;
using System.Xml;
using System.IO;
using System.Xml.Serialization;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace MapEditor {

    public partial class MapEditor : Form {

            //  Form data
        SGP.CSGP_Direct3D D3D = SGP.CSGP_Direct3D.GetInstance();
        SGP.CSGP_TextureManager TM = SGP.CSGP_TextureManager.GetInstance();

        bool looping = true;

            //  Map data
        Tile[,] Map = new Tile[5, 5];
        Size GridSize;
        Size MapSize;
        bool ShowGrids;

            //  Bitmap
        Bitmap bitmap;
        //Bitmap memoryImage;

            //  Tile data   
        Size TileSize;
        Size TileSetSize;
        //  Tile SelectedTile;

            //  Utilities
        Font font = new Font("Times New Roman", 12);
        Pen pen = new Pen(Color.FromArgb(255, 255, 255)); // white
        Brush textBrush = new SolidBrush(Color.FromArgb(0, 0, 0)); // black 


        public MapEditor() {
            InitializeComponent();

            D3D.Initialize(Minimap_Box, true);
            //D3D.AddRenderTarget(anotherpanel, true);
            TM.Initialize(D3D.Device, D3D.Sprite);
        }

        private void MapEditor_Load(object sender, EventArgs e) {

            //  Initialize Sizes
            GridSize = new Size(5, 5);
            TileSize = new Size(16, 16);
            MapSize = new Size(GridSize.Width * TileSize.Width, GridSize.Height * TileSize.Height);

            ShowGrids = true;

            //  Run Import window
            ImportTile();

            //  Set up data
            pen.Width = 1f;
            pen.Color = Color.FromArgb(0, 0, 0);

            Grid_Width_Num.Value = TileSize.Width;
            Grid_Height_Num.Value = TileSize.Height;

            Grid_Column_Num.Value = GridSize.Width;
            Grid_Row_Num.Value = GridSize.Height;
        }

        public bool Looping {
            get { return looping; }
            set { looping = value; }
        }

        public new void Update() {

        }

        public void Render() {

            D3D.Clear(Minimap_Box, Color.CadetBlue);
            D3D.DeviceBegin();
            D3D.SpriteBegin();

            D3D.DrawRect(new Rectangle(20, 20, 10, 10), Color.IndianRed);      

            D3D.SpriteEnd();
            D3D.DeviceEnd();
            D3D.Present();

        }        

        private void Refresh_Map() {
            MapSize = new Size(GridSize.Width * TileSize.Width, GridSize.Height * TileSize.Height);               
            SplitContainer1.Panel1.AutoScrollMinSize = MapSize;
            SplitContainer1.Panel1.Invalidate();
        }

        private void ImportTile() {

                //  Destroy previous bitmap
            if (bitmap != null)
                bitmap.Dispose();

            OpenFileDialog dlg = new OpenFileDialog();
            if (DialogResult.OK == dlg.ShowDialog()) {
                bitmap = new Bitmap(dlg.FileName);
            }

            tabPage1.AutoScrollMinSize = bitmap.Size;

            Editor_Tab.Size = new Size(Editor_Tab.Size.Width, bitmap.Size.Height + 50);
            Minimap_Box.Top = Editor_Tab.Bottom + 2;
            
            TileSetSize.Width = bitmap.Size.Width / TileSize.Width;
            TileSetSize.Height = bitmap.Size.Height / TileSize.Height;            

            tabPage1.Invalidate();
            Editor_Tab.Invalidate();
        }

        private void Map_Panel_Paint(object sender, PaintEventArgs e) {

            Graphics g = e.Graphics;
            pen.Color = Color.FromArgb(0, 0, 0);

                //  Figure out offset and apply it to rect to fix render prob
            Point offset = new Point(0, 0);
            offset.X += SplitContainer1.Panel1.AutoScrollPosition.X;
            offset.Y += SplitContainer1.Panel1.AutoScrollPosition.Y;

            if (ShowGrids) {
                for (int x = 0; x < GridSize.Width; x++) {
                    for (int y = 0; y < GridSize.Height; y++) {

                        Rectangle rect = Rectangle.Empty;
                        rect.X = x * TileSize.Width + offset.X;
                        rect.Y = y * TileSize.Height + offset.Y;
                        rect.Size = TileSize;
                        e.Graphics.DrawRectangle(Pens.Black, rect);
                    }
                }
            }                              
            Minimap_Box.Invalidate();
        } 

        private void TileSet_Paint(object sender, PaintEventArgs e) {
            Graphics g = tabPage1.CreateGraphics();
            Point offset = new Point(0, 0);

            bitmap.SetResolution(g.DpiX, g.DpiY);
            offset.X += tabPage1.AutoScrollPosition.X;
            offset.Y += tabPage1.AutoScrollPosition.Y;
            e.Graphics.DrawImage(bitmap, offset);

            for (int x = 0; x < TileSetSize.Width; x++){
                for (int y = 0; y < TileSetSize.Height; y++) {

                    Rectangle rect = Rectangle.Empty;
                    rect.X = x * TileSize.Width + offset.X;
                    rect.Y = y * TileSize.Height + offset.Y;
                    rect.Size = TileSize;
                    e.Graphics.DrawRectangle(Pens.Black, rect);
                }
            }
        }





        // *** Interactions *** // 
        private void Show_Grid_Click(object sender, EventArgs e) {
            ShowGrids = !ShowGrids;
            SplitContainer1.Panel1.Invalidate();
        }

        private void New_Grid_Click(object sender, EventArgs e) {

            TileSize.Width = 16;
            TileSize.Height = 16;
            GridSize.Width = 5;
            GridSize.Height = 5;
            ShowGrids = true;

            pen.Width = 1f;
            pen.Color = Color.FromArgb(0, 0, 0);

            Grid_Width_Num.Value = TileSize.Width;
            Grid_Height_Num.Value = TileSize.Height;

            Grid_Row_Num.Value = GridSize.Height;
            Grid_Column_Num.Value = GridSize.Width;

            Refresh_Map();
        }

        private void Save_Click(object sender, EventArgs e) {

                //  Xml doc Creation
            XmlDocument xmlDoc = new XmlDocument();

                //	Root of the xml
            XmlElement rootNode = xmlDoc.CreateElement("Map");
            xmlDoc.AppendChild(rootNode);
                //  The root's child
            XmlElement rootele = xmlDoc.CreateElement("Tiles");
            rootNode.AppendChild(rootele);

                //  Chidren of rootele
            XmlElement userNode = xmlDoc.CreateElement("WorldSettings");

            XmlAttribute attribute = xmlDoc.CreateAttribute("Row");
            attribute.Value = GridSize.Height.ToString();
            userNode.Attributes.Append(attribute);
            attribute = xmlDoc.CreateAttribute("Col");
            attribute.Value = GridSize.Width.ToString();
            userNode.Attributes.Append(attribute);
            attribute = xmlDoc.CreateAttribute("TileWidth");
            attribute.Value = "32";
            userNode.Attributes.Append(attribute);
            attribute = xmlDoc.CreateAttribute("TileHeight");
            attribute.Value = "32";
            userNode.Attributes.Append(attribute);
            attribute = xmlDoc.CreateAttribute("WorldWidth");
            attribute.Value = (MapSize.Width * 2).ToString();
            userNode.Attributes.Append(attribute);
            attribute = xmlDoc.CreateAttribute("WorldHeight");
            attribute.Value = (MapSize.Height * 2).ToString();
            userNode.Attributes.Append(attribute);

            rootele.AppendChild(userNode);

            for (int c = 0; c < GridSize.Width; ++c)
            {
                for (int r = 0; r < GridSize.Height; ++r)
                {
                    userNode = xmlDoc.CreateElement("Tile");
                    attribute = xmlDoc.CreateAttribute("Col");
                    attribute.Value = c.ToString();
                    userNode.Attributes.Append(attribute);
                    attribute = xmlDoc.CreateAttribute("Row");
                    attribute.Value = r.ToString();
                    userNode.Attributes.Append(attribute);                    
                    attribute = xmlDoc.CreateAttribute("Type");
                    int x = r % 3;

                    if (c == 4 && r == 4)
                        x = 4;

                    //else if (c == 15 && (r == 1 || r == 2 || r == 3))
                    //    x = 3;
                    //else if (c == 16 && (r == 1 || r == 2 || r == 3))
                    //    x = 3;
                    //else if (c == 17 && (r == 1 || r == 2 || r == 3))
                    //    x = 3;

                    attribute.Value = x.ToString();
                    userNode.Attributes.Append(attribute);

                    rootele.AppendChild(userNode);
                }
            }

            

            xmlDoc.Save("testmap.xml");
            
        } 

        private void Grid_Width_ValueChanged(object sender, EventArgs e) {
            TileSize.Width = (int)Grid_Width_Num.Value;
            Refresh_Map();
        }

        private void Grid_Height_ValueChanged(object sender, EventArgs e) {
            TileSize.Height = (int)Grid_Height_Num.Value;
            Refresh_Map();
            TileSetSize.Width = bitmap.Size.Width / TileSize.Width;
            TileSetSize.Height = bitmap.Size.Height / TileSize.Height;
        }

        private void Grid_Row_ValueChanged(object sender, EventArgs e) {
            GridSize.Height = (int)Grid_Row_Num.Value;
            Refresh_Map();
            TileSetSize.Width = bitmap.Size.Width / TileSize.Width;
            TileSetSize.Height = bitmap.Size.Height / TileSize.Height;
        }

        private void Grid_Column_ValueChanged(object sender, EventArgs e) {
            GridSize.Width = (int)Grid_Column_Num.Value;
            Refresh_Map();
        }

        private void Import_ToolBar_Click(object sender, EventArgs e) {
            ImportTile();
        }

        private void MapEditor_ResizeEnd(object sender, EventArgs e)  {
            int left_ = SplitContainer1.Panel1.Right;
            int right_ = SplitContainer1.Panel2.Right;
            int bottom_ = SplitContainer1.Panel2.Bottom;

            int top_ = Minimap_Box.Location.Y;

            int offset2 = bottom_ - top_;
            int offset = right_ - (left_ + 10);
            Editor_Tab.Size = new Size(offset, Editor_Tab.Size.Height);
            Minimap_Box.Size = new Size(offset, offset2 - 2);

            tabPage1.AutoScrollMinSize = bitmap.Size;
            tabPage1.Invalidate();
        }

        private void MapEditor_FormClosing(object sender, FormClosingEventArgs e) {
            looping = false;
        }               
    }
}
